package ipcards.events;
import ipcards.*;

import java.util.*;
import java.awt.Point;


/**
Represents an action performed on some cards.

Each PlayerAction has a player, a cardset, and an action.  Player==null if no information is given about which player performed the action.  Cardset==null if it is unspecified which cards the action is performed on.  Generally if cardset==null, the action should be performed on all currently selected cards.
*/
public class PlayerAction extends EventObject {
	/*public static PlayerAction newUnspecified(Object source) {
		return new PlayerAction(source,null,PlayerAction.UNSPECIFIED);
	}*/
	public static PlayerAction newSelectionAdd(Object source, CardSet cards) {
		return new PlayerAction(source,cards,PlayerAction.SELECTION_ADD);
	}
	public static PlayerAction newSelectionRemove(Object source, CardSet cards) {
		return new PlayerAction(source,cards,PlayerAction.SELECTION_REMOVE);
	}
	public static PlayerAction newHold(Object source, CardSet cards) {
		return new PlayerAction(source,cards,PlayerAction.HOLD);
	}
	public static PlayerAction newRelease(Object source, CardSet cards) {
		return new PlayerAction(source,cards,PlayerAction.RELEASE);
	}
	public static PlayerAction newMove(Object source, CardSet cards, Point change) {
		return new PlayerAction(source,cards,PlayerAction.MOVE,change);
	}
	public static PlayerAction newFlip(Object source, CardSet cards) {
		return new PlayerAction(source,cards,PlayerAction.FLIP);
	}
	public static PlayerAction newLocalFlip(Object source, CardSet cards) {
		return new PlayerAction(source,cards,PlayerAction.LOCAL_FLIP);
	}
	public static PlayerAction newShuffle(Object source, CardSet cards) {
		return new PlayerAction(source,cards,PlayerAction.SHUFFLE);
	}
	public static PlayerAction newEndTurn(Object source, CardSet cards) {
		return new PlayerAction(source,cards,PlayerAction.END_TURN);
	}
	public static PlayerAction newShowDialog(Object source, String message) {
		return new PlayerAction(source,PlayerAction.SHOW_DIALOG, message.replaceAll(DEL,"\t"));
	}
	
	//##########################################################################################################################################################
	//############ FOR THE LOVE OF GOD DO NOT USE 32 or 10 or 13 or AS THE VALUE FOR ONE OF THESE (32 is the value of the delimiter assuming it is still a space) #############
	//##########################################################################################################################################################
	public static final String DEL = " ";
	public static final char UNSPECIFIED = 0;
	public static final char SELECTION_ADD = 1;
	public static final char SELECTION_REMOVE = 2;
	public static final char HOLD = 3;
	public static final char MOVE = 4;
	public static final char FLIP = 5;
	public static final char SHUFFLE = 6;
	public static final char RELEASE = 7;
	public static final char SYNC_LOCATIONS = 8;
	public static final char END_TURN = 9;
	public static final char LOCAL_FLIP = 11;
	public static final char NEW_GAME = 12;
	public static final char ADD_DECK = 14;
	public static final char SET_FACE_UP = 15;
	public static final char SET_FACE_DOWN = 16;
	public static final char RESET_LOCAL_FLIP = 27;
	public static final char RESET_LOCAL_FLIP_TOALL = 28;
	public static final char CUSTOM = 18;
	public static final char SHOW_DIALOG = 19;
	public static final char SEND_NAME_HASHMAP = 20;
	public static final char DISCONNECT = 21;

	
	private Player player;
	private CardSet cards;
	private char action;
	private Point change;
	private String args;
	
	/**
	@param source the object where this action originated
	@param cards the set of cards the action is applied to.  if null, the action is applied to the currently held cards.
	@param action the action to be performed
	*/

	public PlayerAction(Object source, Player player, CardSet cards, char action, Point change, String args) {

		super(source);
		this.player = player;
		this.cards = cards;
		this.action = action;
		this.args = args;
		if (change==null) this.change = new Point(0,0);
		else this.change = change;
	}
	
	public PlayerAction(Object source, CardSet cards, char action, Point change, String args) {
		this(source,null,cards,action,change,args);
	}
	
	public PlayerAction(Object source, CardSet cards, char action, Point change) {
		this(source,cards,action,change, null);
	}
	
	
	public String getArgs() {
		return args;
	}
	public PlayerAction(Object source, CardSet cards, char action) {
		this(source,cards,action,null);
	}
	
	public PlayerAction(Object source, char action) {
		this(source,null,action,null);
	}
	
	public PlayerAction(Object source, char action, String args) {
		this(source,null,action,null, args);
	}	
	
	public static PlayerAction newCustomPlayerAction(Object source, char action, String args) {
		return new PlayerAction(source, CUSTOM, action + args);
	}
	
	public static PlayerAction newCustomPlayerAction(Object source, char action, CardSet cards, String args) {
		String cardlength = "";				//number of digits in a given card's id
		String cardnumbers = "";
//WARNING: WILL NOT HANDLE >= 1,000,000,000	CARDS IN THE CARDSET "cards"
		for(Card c: cards.getZAscendingList()){
//			int cardnum = c.getImmutableID();
int cardnum = c.getID();			
			//int cardnum = c.getID();
			int numdigits = 1;
			while(cardnum >= 10){
				numdigits++;
				cardnum = (int)(cardnum/10);
			}
			cardlength = cardlength + numdigits;
//			cardnumbers = cardnumbers + c.getImmutableID();
cardnumbers = cardnumbers + c.getID();			
		}	
		return new PlayerAction(source, cards, CUSTOM, null, action + " " + cards.size() + ":" + cardlength + ":" + cardnumbers + ":" + args);
	}
	
	public CardSet getCards() {
		return cards;
	}
	
	public char getAction() {
		return action;
	}
	
	public Point getChange() {
		return change;
	}
	
	public String toString() {
		return super.toString();
	}
	
	public Object getSource() {
		return source;
	}
	
	//just returns the first arg
	public char getCustomAction() {
		return args.split(DEL)[0].charAt(0);
	}
}












